import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Properties;

public class EventDataBase {
    private final HashMap<String, EventCollects> eventDataBase;
    private boolean isPulled;
    private final String userClass;
    private final String userName;
    private final String workDirectory;

    public EventDataBase(String workDirectory, String userClass, String userName) {
        this.userClass = userClass;
        this.userName = userName;
        this.workDirectory = workDirectory;
        this.eventDataBase = new HashMap<>();
        this.isPulled = false;
    }

    public void pushAllCollects() throws IOException {
        if (!this.isPulled) {
            LogHelper.messageError(this, "pushAllCollects",
                    "尚未载入任何 dataBaseProperties！无法进行 push");
            return;
        }

        for (EventCollects collects : this.eventDataBase.values()) {
            if (collects.getCollectsName().compareTo(this.userClass) != 0) {
                collects.pushToFile(this.workDirectory);
            } else if (this.userName.compareTo("Admin") == 0) {
                collects.pushToFile(this.workDirectory);
            }
        }
    }

    public void pullAllCollectsFromProperties(HashMap<String, EventCollects> eventCollectsPool) throws FileNotFoundException {
        if (this.isPulled) {
            return;
        }

        String userInfo = this.userClass + this.userName + ".properties";
        Properties dataBaseProperties = new Properties();
        InputStream fileInput = new FileInputStream(userInfo);

        try {
            dataBaseProperties.load(new InputStreamReader(fileInput, StandardCharsets.UTF_8));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        Enumeration<?> iteration = dataBaseProperties.propertyNames();

        while (iteration.hasMoreElements()) {
            String key = (String) iteration.nextElement();
            String collectsName = dataBaseProperties.getProperty(key);
            EventCollects collects = eventCollectsPool.get(collectsName);

            if (collects == null) {
                collects = new EventCollects(collectsName);
                eventCollectsPool.put(collectsName, collects);
            }

            try {
                collects.pullFromFile(this.workDirectory);
            } catch (IOException e) {
                LogHelper.messageError(this, "pullAllCollectsFromProperties",
                        "从 properties 载入 EventCollects 发生错误！");
                throw new RuntimeException(e);
            }
            this.eventDataBase.put(collectsName, collects);
        }
        this.isPulled = true;
    }

    public EventCollects query(long since, long until) {
        LogHelper.messageInfo(this, "query",
                "查询从 " + since + " 到 " + until + " 的事件，是否载入:" + this.isPulled);

        if (since <= 0 || since >= until) {
            return null;
        }

        EventCollects resultCollects = new EventCollects("nullFile");

        for (EventCollects collects : this.eventDataBase.values()) {
            for (EventItem item : collects.getEventItems()) {
                if (item.getEndDate() >= since && item.getEndDate() <= until) {
                    resultCollects.addEventItem(item);
                }
            }
        }

        resultCollects.sortAsEndDate();
        return resultCollects;
    }

    public void insertEventItem(String collectsName, long endDate, String eventName,
                                String eventContent, boolean isLongTermEvent) {
        EventCollects collects = this.eventDataBase.get(collectsName);
        if (collects == null) {
            LogHelper.messageError(this, "insertEventItem",
                    "未发现事件集 <" + collectsName + ">");
            return;
        }

        if (collects.isFind(endDate, eventName)) {
            collects.deleteEventItem(endDate, eventName);
        }

        collects.addEventItem(endDate, eventName, eventContent, isLongTermEvent);
        try {
            this.pushAllCollects();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public void deleteEventItem(String collectsName, long endDate, String eventName) {
        EventCollects collects = this.eventDataBase.get(collectsName);
        if (collects == null) {
            LogHelper.messageError(this, "deleteEventItem",
                    "未发现事件集 <" + collectsName + ">");
            return;
        }

        collects.deleteEventItem(endDate, eventName);
        try {
            this.pushAllCollects();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
